#include "guish.hpp"
#include <sys/wait.h>

ProcessManager *processManager = NULL;

ProcessManager::ProcessManager()
{
	pthread_mutex_init(&lock, NULL);
}

ProcessManager::~ProcessManager()
{
	pthread_mutex_destroy(&lock);
}

void ProcessManager::takeLock()
{
	pthread_mutex_lock(&lock);
}

void ProcessManager::releaseLock()
{
	pthread_mutex_unlock(&lock);
}

void ProcessManager::checkChildren()
{
	// Collect zombie children
	int status = 0;
	int pid = waitpid(-1, &status, WNOHANG);
	if(pid > 0)
	{
		finishProcess(pid, status);
	}
}

void ProcessManager::registerNewProcess(Process *process)
{
	int pid = process->getPid();
	processes[pid] = process;
}


int ProcessManager::getResult(int pid)
{
	pthread_mutex_lock(&lock);
		map<int,int>::iterator it = results.find(pid);
		int ret;
		if(it != results.end())
			ret = it->second;
		else
			ret = -1;
	pthread_mutex_unlock(&lock);
	
	return ret;
}

void ProcessManager::forgetResult(int pid)
{
	pthread_mutex_lock(&lock);
		results.erase(pid);
	pthread_mutex_unlock(&lock);
}

void ProcessManager::finishProcess(int pid, int status)
{
	pthread_mutex_lock(&lock);
		map<int, Process*>::iterator it = processes.find(pid);
		if(it==processes.end()) {
			pthread_mutex_unlock(&lock);
			return;
		}
		Process *process = it->second;
		
		results[pid] = status;
	pthread_mutex_unlock(&lock);
	
	Job *job = process->getOwner();
	if(job) job->processFinished(pid, status);
}

bool ProcessManager::processIsFinished(int pid)
{
	bool ret;
	pthread_mutex_lock(&lock);
		ret = (results.find(pid) != results.end());
	pthread_mutex_unlock(&lock);
	return ret;
}

